home *** CD-ROM | disk | FTP | other *** search
Text File | 2000-09-28 | 14.5 KB | 506 lines | [TEXT/CWIE] |
- /*
- File: GetSetOptions.c
-
- Contains: Sample for getting and setting options using the various
- option management routines.
-
- Written by: Quinn "The Eskimo!"
-
- Copyright: Copyright © 1997-1999 by Apple Computer, Inc., All Rights Reserved.
-
- You may incorporate this Apple sample source code into your program(s) without
- restriction. This Apple sample source code has been provided "AS IS" and the
- responsibility for its operation is yours. You are not permitted to redistribute
- this Apple sample source code as "Apple sample source code" after having made
- changes. If you're going to re-distribute the source, we require that you make
- it clear in the source that the code was descended from Apple sample source
- code, but that you've made changes.
-
- Change History (most recent first):
- 7/22/1999 Karl Groethe Updated for Metrowerks Codewarror Pro 2.1
-
-
- */
-
- /////////////////////////////////////////////////////////////////////
- // The OT debugging macros in <OTDebug.h> require this variable to
- // be set.
-
- #ifndef qDebug
- #define qDebug 1
- #endif
-
- /////////////////////////////////////////////////////////////////////
- // Pick up all the standard OT stuff.
-
- #include <OpenTransport.h>
-
- /////////////////////////////////////////////////////////////////////
- // Pick up all the OT TCP/IP stuff.
-
- #include <OpenTptInternet.h>
-
- /////////////////////////////////////////////////////////////////////
- // Pick up all the OT serial stuff.
-
- #include <OpenTptSerial.h>
-
- /////////////////////////////////////////////////////////////////////
- // Pick up the OTDebugBreak and OTAssert macros.
-
- #include <OTDebug.h>
-
- /////////////////////////////////////////////////////////////////////
- // Standard C prototypes.
-
- #include <stdio.h>
-
- /////////////////////////////////////////////////////////////////////
- // OTDebugStr is not defined in any OT header files, but it is
- // exported by the libraries, so we define the prototype here.
-
- extern pascal void OTDebugStr(const char* str);
-
- /////////////////////////////////////////////////////////////////////
-
- static OTResult SetFourByteOption(EndpointRef ep,
- OTXTILevel level,
- OTXTIName name,
- UInt32 value)
- // level and name must denote a four byte option that is
- // appropriate for the endpoint ep. This routine sets the
- // option to value. ep is assumed to be in synchronous
- // mode.
- //
- // If all goes well, the result is noErr. If an error
- // occurs, the result is negative. If the option could not
- // be negotiated, a positive result being one of (T_FAILURE,
- // T_PARTSUCCESS, T_READONLY, T_NOTSUPPORT) is returned
- {
- OTResult err;
- TOption option;
- TOptMgmt request;
- TOptMgmt result;
-
- // Set up the option buffer to reflect the specific option
- // and value we want to set. We use a TOption structure
- // to represent the option buffer. TOption is specifically
- // defined to allow easy construction of 4 byte options.
- // If you want to negotiate different size options, or
- // multiple options in a single call, then constructing
- // the option buffer is a little trickier
-
- option.len = kOTFourByteOptionSize;
- option.level = level;
- option.name = name;
- option.status = 0;
- option.value[0] = value;
-
- // Set up the request for OTOptionManagement to point
- // to the option buffer we just filled out, and tell
- // it that we want to negotiate (ie set) the option.
-
- request.opt.buf = (UInt8 *) &option;
- request.opt.len = sizeof(option);
- request.flags = T_NEGOTIATE;
-
- // Set up the reply for OTOptionManagement. This is where
- // OTOptionManagement puts the result of the negotiation.
-
- result.opt.buf = (UInt8 *) &option;
- result.opt.maxlen = sizeof(option);
-
- // Call OTOptionManagement and then check that the value
- // was negotiated successfully. Any value other than
- // T_SUCCESS is reported via the error result.
-
- err = OTOptionManagement(ep, &request, &result);
-
- if (err == noErr) {
- if (option.status != T_SUCCESS) {
- err = option.status;
- }
- }
-
- return (err);
- }
-
- /////////////////////////////////////////////////////////////////////
-
- static OTResult GetFourByteOption(EndpointRef ep,
- OTXTILevel level,
- OTXTIName name,
- UInt32 *value)
- // level and name must denote a four byte option that is
- // appropriate for the endpoint ep. This routine gets the
- // current option setting and puts it in the the variable
- // pointed to by value. ep is assumed to be in synchronous
- // mode.
- //
- // If all goes well, the result is noErr. If an error
- // occurs, the result is negative. If the option could not
- // be read, a positive result being one of (T_FAILURE,
- // T_PARTSUCCESS, T_NOTSUPPORT) is returned
- {
- OTResult err;
- TOption option;
- TOptMgmt request;
- TOptMgmt result;
-
- // Set up the option buffer to reflect the specific option
- // and value we want to set. We use a TOption structure
- // to represent the option buffer. TOption is specifically
- // defined to allow easy construction of 4 byte options.
- // If you want to negotiate different size options, or
- // multiple options in a single call, then constructing
- // the option buffer is a little trickier
-
- option.len = kOTFourByteOptionSize;
- option.level = level;
- option.name = name;
- option.status = 0;
- option.value[0] = 0; // Ignored because we're getting the value.
-
- // Set up the request for OTOptionManagement to point
- // to the option buffer we just filled out, and tell
- // it that we want to get the current value of the option.
-
- request.opt.buf = (UInt8 *) &option;
- request.opt.len = sizeof(option);
- request.flags = T_CURRENT;
-
- // Set up the reply for OTOptionManagement. This is where
- // OTOptionManagement puts the result of the negotiation.
-
- result.opt.buf = (UInt8 *) &option;
- result.opt.maxlen = sizeof(option);
-
- // Call OTOptionManagement and then check that the value
- // was read successfully. Any status other than
- // T_SUCCESS or T_READONLY is reported via the error
- // result.
-
- err = OTOptionManagement(ep, &request, &result);
-
- if (err == noErr) {
- switch (option.status) {
- case T_SUCCESS:
- case T_READONLY:
- *value = option.value[0];
- break;
- default:
- err = option.status;
- break;
- }
- }
-
- return (err);
- }
-
- /////////////////////////////////////////////////////////////////////
-
- static OSStatus PrintOptionBuffer(const TNetbuf *optionBuffer)
- // Print a summary of the optionBuffer to stdout.
- // Basically the call enumerates the option buffer using
- // OTNextOption, and prints the level, name, size and status
- // of each of the options in the buffer.
- {
- OSStatus err;
- TOption *currentOption;
-
- currentOption = nil;
- do {
- err = OTNextOption(optionBuffer->buf, optionBuffer->len, ¤tOption);
- if (err == noErr && currentOption != nil) {
- printf("Level = $%08x, Name = $%08x, Data Length = %d, Status = $%08x\n",
- currentOption->level,
- currentOption->name,
- currentOption->len - kOTOptionHeaderSize,
- currentOption->status);
- }
- } while (err == noErr && currentOption != nil);
-
- return (err);
- }
-
- /////////////////////////////////////////////////////////////////////
-
- static OSStatus PrintAllOptionsAtLevel(EndpointRef ep, OTXTILevel level)
- // Gets all of the options for the endpoint ep at the specified
- // level and prints a summary of them to stdout.
- {
- OSStatus err;
- TEndpointInfo epInfo;
- TOptionHeader requestOption;
- void *resultOptionBuffer;
- TOptMgmt request;
- TOptMgmt result;
-
- resultOptionBuffer = nil;
-
- // First call OTGetEndpointInfo to find out the maximum
- // size of the options for this type of endpoint and then
- // allocate that size buffer to hold the resulting options.
-
- err = OTGetEndpointInfo(ep, &epInfo);
- if (err == noErr) {
- resultOptionBuffer = OTAllocMem(epInfo.options);
- if (resultOptionBuffer == nil) {
- err = kENOMEMErr;
- }
- }
-
- // Call OTOptionManagement to get the current value (T_CURRENT)
- // of all of the options (ie T_ALLOPT) of the specified level.
- // The resulting options go into resultOptionBuffer, which we
- // have just allocated.
-
- if (err == noErr) {
- requestOption.len = kOTOptionHeaderSize;
- requestOption.level = level;
- requestOption.name = T_ALLOPT;
- requestOption.status = 0;
-
- request.opt.buf = (UInt8 *) &requestOption;
- request.opt.len = sizeof(requestOption);
- request.flags = T_CURRENT;
-
- result.opt.buf = resultOptionBuffer;
- result.opt.maxlen = epInfo.options;
-
- err = OTOptionManagement(ep, &request, &result);
- }
-
- // Now that we have the options, print them to stdout.
-
- if (err == noErr) {
- err = PrintOptionBuffer(&result.opt);
- printf("\n");
- }
-
- // Clean up.
-
- if (resultOptionBuffer != nil) {
- OTFreeMem(resultOptionBuffer);
- }
-
- return (err);
- }
-
- /////////////////////////////////////////////////////////////////////
-
- static OSStatus PrintOptionsForConfiguration(const char *configStr, OTXTILevel level)
- // Get all the options associated with a specific level of a specific
- // OT provider (eg configStr) and then convert those options to a
- // formatted string and output that string.
- {
- OSStatus err;
- OSStatus junk;
- EndpointRef ep;
- TEndpointInfo epInfo;
- TOptionHeader requestOption;
- void *resultOptionBuffer;
- TOptMgmt request;
- TOptMgmt result;
- TOption *resultOption;
- char optionsString[1024];
-
- resultOptionBuffer = nil;
- ep = kOTInvalidEndpointRef;
-
- // First create an endpoint using the specified configuration.
- // Note that we pass in epInfo to be filled out with the various
- // parameters of this endpoint, including it's maximum option
- // buffer size.
-
- ep = OTOpenEndpoint(OTCreateConfiguration(configStr), 0, &epInfo, &err);
-
- // Now allocate a buffer of the maximum option buffer size.
-
- if (err == noErr) {
- resultOptionBuffer = OTAllocMem(epInfo.options);
- if (resultOptionBuffer == nil) {
- err = kENOMEMErr;
- }
- }
-
- // Call OTOptionManagement to get the current value (T_CURRENT)
- // of all of the options (ie T_ALLOPT) of the specified level.
- // The resulting options go into resultOptionBuffer, which we
- // have just allocated.
-
- if (err == noErr) {
- requestOption.len = kOTOptionHeaderSize;
- requestOption.level = level;
- requestOption.name = T_ALLOPT;
- requestOption.status = 0;
-
- request.opt.buf = (UInt8 *) &requestOption;
- request.opt.len = sizeof(requestOption);
- request.flags = T_CURRENT;
-
- result.opt.buf = resultOptionBuffer;
- result.opt.maxlen = epInfo.options;
-
- err = OTOptionManagement(ep, &request, &result);
- }
-
- // Now use OTCreateOptionString to convert the resulting
- // buffer full of options into a formatted string, and then print
- // that formatted string to stdout.
-
- if (err == noErr) {
- resultOption = (TOption *) result.opt.buf;
- err = OTCreateOptionString(configStr, &resultOption, result.opt.buf + result.opt.len, optionsString, 1024);
- if (err == noErr) {
- printf("Formatted Options = “%s”\n\n", optionsString);
- }
- }
-
- // Clean up.
-
- if (resultOptionBuffer != nil) {
- OTFreeMem(resultOptionBuffer);
- }
- if (ep != kOTInvalidEndpointRef) {
- junk = OTCloseProvider(ep);
- OTAssert("PrintOptionsForConfiguration: Closing the endpoint failed", junk == noErr);
- }
-
- return (err);
- }
-
- /////////////////////////////////////////////////////////////////////
-
- static OSStatus BuildAndPrintOptions(const char *configStr, const char *optionsString)
- // Given a configuration string and a set of formatted options, converts
- // the options to their binary format (ie an options buffer) and then
- // prints that buffer to stdout.
- {
- OSStatus err;
- OSStatus junk;
- void *resultOptionBuffer;
- EndpointRef ep;
- TEndpointInfo epInfo;
- TNetbuf optionsNetbuf;
-
- resultOptionBuffer = nil;
- ep = kOTInvalidEndpointRef;
-
- // First create an endpoint using the specified configuration.
- // Note that we pass in epInfo to be filled out with the various
- // parameters of this endpoint, including it's maximum option
- // buffer size.
-
- ep = OTOpenEndpoint(OTCreateConfiguration(configStr), 0, &epInfo, &err);
-
- // Now allocate a buffer of the maximum option buffer size.
-
- if (err == noErr) {
- resultOptionBuffer = OTAllocMem(epInfo.options);
- if (resultOptionBuffer == nil) {
- err = kENOMEMErr;
- }
- }
-
- // Call OTCreateOptions to parse the formatted optionsString into
- // the binary format (optionsNetbuf), and then use PrintOptionBuffer
- // to output that buffer to stdout.
-
- if (err == noErr) {
- optionsNetbuf.buf = resultOptionBuffer;
- optionsNetbuf.len = 0;
- optionsNetbuf.maxlen = epInfo.options;
- err = OTCreateOptions(configStr, (char **) &optionsString, &optionsNetbuf);
-
- if (err == noErr) {
- err = PrintOptionBuffer(&optionsNetbuf);
- printf("\n");
- }
- }
-
- // Clean up.
-
- if (resultOptionBuffer != nil) {
- OTFreeMem(resultOptionBuffer);
- }
- if (ep != kOTInvalidEndpointRef) {
- junk = OTCloseProvider(ep);
- OTAssert("BuildAndPrintOptions: Closing the endpoint failed", junk == noErr);
- }
-
- return (err);
- }
-
- /////////////////////////////////////////////////////////////////////
-
- void main(void)
- // A simple main line that demonstrates the use of the various
- // functions defined above. The basic idea is to create
- // an endpoint, get the value of the IP_REUSEADDR option, then
- // change it to true, and read it back to verify that the change
- // worked. We then do a few other interesting things with
- // various miscellaneous options API routines.
- {
- OSStatus err;
- OSStatus junk;
- EndpointRef ep;
- UInt32 value;
-
- printf("Hello Cruel World!\n");
-
- err = InitOpenTransport();
-
- if (err == noErr) {
-
- ep = OTOpenEndpoint(OTCreateConfiguration(kTCPName), 0, nil, &err);
- if (err == noErr) {
-
- printf("\nGetting and Setting IP_REUSEADDR.\n");
-
- err = GetFourByteOption(ep, INET_IP, IP_REUSEADDR, &value);
- if (err == noErr) {
- printf("Default value = %d\n", value);
- }
- if (err == noErr) {
- err = SetFourByteOption(ep, INET_IP, IP_REUSEADDR, true);
- }
- if (err == noErr) {
- err = GetFourByteOption(ep, INET_IP, IP_REUSEADDR, &value);
- if (err == noErr) {
- printf("New value = %d\n", value);
- }
- }
-
- if (err == noErr) {
- printf("\nPrinting Options Piecemeal at Level INET_IP.\n");
- err = PrintAllOptionsAtLevel(ep, INET_IP);
- }
-
- if (err == noErr) {
- printf("\nPrinting Formatted Options at Level COM_SERIAL.\n");
- err = PrintOptionsForConfiguration(kSerialName, COM_SERIAL);
- }
-
- if (err == noErr) {
- printf("\nBuilding Options for COM_SERIAL.\n");
- err = BuildAndPrintOptions(kSerialName, "BaudRate=9600, DataBits=7, StopBits=15");
- }
-
- junk = OTCloseProvider(ep);
- OTAssert("GetSetOptions: Closing the endpoint failed", junk == noErr);
- }
-
- CloseOpenTransport();
- }
-
- if (err == noErr) {
- printf("Success.\n");
- } else {
- printf("Failed with error %d.\n", err);
- }
- printf("Done. Press command-Q to Quit.\n");
- }
-
-
-